<template>
    <div>
        <DataSearchBar :columns="searchColumns" :config="config" @search="search" @reset="searchReset"
            v-if="!tableConfig.tableSearchHide">
            <template #search>
                <slot name="search"></slot>
            </template>
        </DataSearchBar>
        <div>
            <div><slot name="tableoperbefore"></slot></div>
            <!-- v-hasPermi="[ PerKey ? `${PerKey}:add` : '']" -->
            <div class="tableoper_container" v-if="!tableConfig.operBarHide">
                <div>
                    <el-button type="primary" plain :icon="Plus" v-if="!tableConfig.addBtnHide" 
                        @click="add" v-hasPermi="[ PerKey ? `${PerKey}:add` : '*:*:*' ]" >{{ tableConfig.addBtnText || '新 增' }}</el-button>
                    <el-button type="default" :icon="Download" v-if="tableConfig.importBtnShow"
                        @click="importData" v-hasPermi="[ PerKey ? `${PerKey}:import` : '*:*:*' ]">{{ tableConfig.importBtnText || '导 入' }}</el-button>
                    <el-button type="default" :icon="Upload" v-if="tableConfig.exportBtnShow"
                        @click="exportData" v-hasPermi="[ PerKey ? `${PerKey}:export` : '*:*:*' ]">{{ tableConfig.exportBtbText || '导 出' }}</el-button>
                    <slot name="tableoper"></slot>
                </div>
                <div class="flex flex-end table_tool_container">
                    <el-button circle v-if="tableSearchBtnShow"
                        :type="tableConfig.tableSearchHide ? 'primary': null" @click="searchBar_switch">
                        <i class="icon-base icon-base-sousuo"></i>
                    </el-button>
                    <el-button circle @click="refreshTable">
                        <i class="icon-base icon-base-qiehuangongsi"></i>
                    </el-button>
                    <el-popover placement="right-start" :width="180" trigger="click">
                        <template #reference>
                            <el-button circle> <i class="icon-base icon-base-lie"></i></el-button>
                        </template>
                        <el-checkbox-group v-model="tableColumnCheckList">
                            <el-row :gutter="24">
                                <el-col :span="24">
                                    <el-checkbox label="#" :disabled="indexDiabled"
                                        @click.native="($event) => { changeColumsState({ title: '#', key: '#' }, 0, $event) }"
                                    >#</el-checkbox>
                                </el-col>
                                <el-col :span="24" v-for="(item, index) in tableColumnOper" :key="item.key">
                                    <el-checkbox :label="item.key" :disabled="item.columnDisabled"
                                        @click.stop="($event) => { changeColumsState(item, index + 1, $event) }">
                                        {{ item.title }}
                                    </el-checkbox>
                                </el-col>
                            </el-row>
                        </el-checkbox-group>
                    </el-popover>
                </div>
            </div>
            <div><slot name="tableoperlast"></slot></div>
            <el-table :data="data" scrollbar-always-on v-loading="tableLoading" style="width: 100%" :border="true" 
                @selection-change="selectionChange">
                <el-table-column type="selection" fixed="left" width="45" align="center" v-if="tableConfig.selection" />
                <el-table-column type="index" fixed="left" label="#" width="45" align="center" v-if="tableConfig.index" />
                <el-table-column :fixed="item.fixed ? 'left' : null" :prop="item.key" :label="item.title" 
                    :minWidth="item.minWidth || null" :width="item.width" :align="item.align || 'left'"
                    :show-overflow-tooltip="item.showTooltip"
                    v-for="(item, index) in tempArray" :key="item.key">
                    <template #default="scope">
                        <span v-if="!item.tableCustom">
                            {{ scope.row[item.key] == '0' ? 0 : scope.row[item.key] ? scope.row[item.key] : '-' }}
                        </span>
                        <slot v-else :name="item.key" :row="scope.row"></slot>
                        <el-table-column :label="cItem.title" :prop="cItem.key" 
                            :minWidth="cItem.minWidth || null" :width="cItem.width" :align="cItem.align || 'left'"
                            :show-overflow-tooltip="cItem.showTooltip"
                            v-for="cItem in item.children" :key="cItem.key">
                            <template #default="scope">
                                <span v-if="!cItem.tableCustom">
                                    {{ scope.row[cItem.key] == '0' ? 0 : scope.row[cItem.key] ? scope.row[cItem.key] : '-' }}
                                </span>
                                <slot v-else :name="cItem.key" :row="scope.row"></slot>
                                <el-table-column :label="sItem.title" :prop="sItem.key" 
                                    :minWidth="sItem.minWidth || null" :width="sItem.width" :align="sItem.align || 'left'"
                                    :show-overflow-tooltip="sItem.showTooltip"
                                    v-for="sItem in cItem.children" :key="sItem.key">
                                    <template #default="scope">
                                        <span v-if="!sItem.tableCustom">
                                            {{ scope.row[sItem.key] == '0' ? 0 : scope.row[sItem.key] ? scope.row[sItem.key] : '-' }}
                                        </span>
                                        <slot v-else :name="sItem.key" :row="scope.row"></slot>
                                    </template>
                                </el-table-column>
                            </template>
                        </el-table-column>
                    </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" v-if="!tableConfig.rowOperHide" 
                    :width="tableConfig.rowOperWidth || 180" align="center">
                    <template #default="scope" class="flex">
                        <el-button type="primary" link v-if="!tableConfig.editBtnHide" 
                            @click="edit(scope.row)" v-hasPermi="[ PerKey ? `${PerKey}:edit` : '*:*:*' ]">编 辑</el-button>
                        <el-divider direction="vertical" v-if="!tableConfig.removeBtnHide" />
                        <el-button type="danger" link v-if="!tableConfig.removeBtnHide" 
                            @click="remove(scope.row)" v-hasPermi="[ PerKey ? `${PerKey}:remove` : '*:*:*' ]">删 除</el-button>
                        <slot name="tablerow" :row="scope.row"></slot>
                    </template>
                </el-table-column>
            </el-table>
            <div class="pagination_container" v-if="total > 0">
                <el-pagination v-model:current-page="paginationParam.currentPage" v-model:page-size="paginationParam.pageSize" 
                    :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next, jumper" background
                    :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
            </div>
        </div>
        <DataFormBar v-model:show="formShow" :columns="formColumns" :config="config" :defaultValue="defaultValue" 
            :state="formState" :title="formTitle"
            @confirm="formConfirm"></DataFormBar>
    </div>
</template>
<script setup>
    import { ref, reactive, computed } from "vue";
    import DataSearchBar from "./DataSearchBar.vue";
    import DataFormBar from "./DataFormBar.vue";
    import { Plus, Download, Upload } from '@element-plus/icons-vue'
    const route = useRoute();
    const props = defineProps( [ 'config', 'data', 'columns', 'pages', 'total', 'loading', 'PerKey' ] ); // 接收传参
    const emit = defineEmits( [ 'confirm', 'search', 'reset', 'remove' , 'selectionChange', 'currentChange', 'sizeChange', 'edit', 'addBefore', 'editBefore', 
        'refresh', 'export', 'import' ] ); // 回调注册
    // -------------------表格配置--------------------------
    const tableConfig = reactive(props.config || {});
    const tableColumns = reactive(props.columns || [])
    const tableColumnOper = reactive( tableColumns.filter( item => !item.hide) || [] )
    const tableLoading = ref(false);
    let tempArray = computed( () => { return tableColumns.filter( item => !item.hide) || [] } );
    watch(() => props.loading, () => { 
        tableLoading.value = props.loading;
        if(props.loading) tableColumnHideChange();
    });
    const selectionChange = (rows) => {
        emit('selectionChange', rows)
    };
    // -------------------分页配置--------------------------
    const paginationParam = ref({
        currentPage: props.pages ? props.pages.page_current : 1,
        pageSize: props.pages ? props.pages.page_size : 10,
    });

    let saveColumnsList = reactive([]);
    const tableOperColumnCheckList = ref([]);
    const showColumnsList = ref([]);
    const tableColumnCheckList = ref([]);
    const indexDiabled = ref(false);
    const tableColumnHideChange = () => {
        saveColumnsList = localStorage.getItem( tableConfig.tableName || route.name ) 
            ? localStorage.getItem( tableConfig.tableName || route.name ).split(',') 
            : []; // 获取当前页 列显隐配置

        if( saveColumnsList.length <= 0 ){
            showColumnsList.value = tableColumns.filter( item => !item.hide); // 未启用hide列配置项过滤
            tableColumnCheckList.value = showColumnsList.value.map( item => item.key); // 提取未启用hide列配置项的key值数组
            if(props.config.index) tableColumnCheckList.value.unshift('#');
        }else{
            if(saveColumnsList.length == 1){
                const onlyKey = saveColumnsList[0];
                if(onlyKey == '#') {
                    indexDiabled.value = true;
                }else{
                    const index = tableColumns.findIndex(item => item.key == onlyKey);
                    tableColumns[index].columnDisabled = true
                }
            }
            tableColumnCheckList.value = saveColumnsList;
            tableConfig.index = false;
            tableColumnCheckList.value.map(item => {
                if(item == '#'){
                    tableConfig.index = true;
                    return
                }
            }); 
            tableColumns.map( item => {
                const index = tableColumnCheckList.value.findIndex(cItem => cItem == item.key);
                item.hide = index < 0 ? true : false;
            })
        }
        tableOperColumnCheckList.value = tableColumnCheckList.value && tableColumnCheckList.value.length 
            ? tableColumnCheckList.value.toString().split(',') 
            : []; // 深度复制
    };
    const handleSizeChange = (size) => {
        emit('sizeChange', size)
    };
    const handleCurrentChange = (current) => {
        emit('currentChange', current)
    };
    const changeColumsState = (checkItem, checkIndex, e) => {
        if(e.target.tagName == 'INPUT') return // 跳过INPUT点击触发
        const index = tableOperColumnCheckList.value.findIndex( item => checkItem.key == item );
        if(index < 0){
            tableOperColumnCheckList.value.push(checkItem.key);
            setColumnContralresult(checkItem, true);
        }else{
            tableOperColumnCheckList.value.splice(index, 1);
            setColumnContralresult(checkItem, false);
        }
        localStorage.setItem( tableConfig.tableName || route.name, tableOperColumnCheckList.value)
        const count = tableOperColumnCheckList.value.length;
        if(count <= 1) { 
            const onlyKey = tableOperColumnCheckList.value[0];
            if(onlyKey == '#') {
                indexDiabled.value = true;
                return
            }
            const index = tableColumns.findIndex(item => item.key == onlyKey);
            tableColumns[index].columnDisabled = true
        }else{
            indexDiabled.value = false;
            tableColumns.map(item => {
                item.columnDisabled = false;
            }) 
        }
    };
    const setColumnContralresult = (checkItem, state) => {
        if(checkItem.key == '#'){
            tableConfig.index = state
            return
        }
        const index = tableColumns.findIndex(item => item.key == checkItem.key);
        tableColumns[index].hide = !state
    };
    // -------------------搜索配置--------------------------
    const tableSearchBtnShow = ref(true);
    let searchColumns = computed( () => { return tableColumns.filter( item => item.search) || [] } );
    if(searchColumns.value.length <= 0) { tableSearchBtnShow.value = false; }
    const searchParamForm = ref({});
    const search = (searchParam) => {
        searchParamForm.value = searchParam;
        emit('search', searchParam);
    };
    const searchReset = () => {
        emit('reset');
    };
    const refreshTable = () => {
        emit('refresh', searchParamForm.value)
    };
    const searchBar_switch = () => {
        tableConfig.tableSearchHide = !tableConfig.tableSearchHide;
    };
    // -------------------表单配置--------------------------
    let formColumns = computed( () => { return tableColumns.filter( item => item.formShow) || [] } );
    const formShow = ref(false);
    const formState = ref(true); // true:创建  false: 编辑
    const formTitle = ref('编 辑');
    const defaultValue = ref({});
    const add = () => {
        formState.value = true;
        emit('addBefore');
        if(tableConfig.editCustom) {
            emit('edit', formState.value);
            return
        }
        formTitle.value = tableConfig.formAddTitle || '新 增';
        defaultValue.value = {};
        formShow.value = true;
    };
    const edit = (rowData) => {
        formState.value = false;
        emit('editBefore', rowData);
        if(tableConfig.editCustom) {
            emit('edit', formState.value, rowData);
            return
        }
        formTitle.value = tableConfig.formEditTitle || '编 辑';
        formColumns.value.map(item => {
            defaultValue.value[item.key] = rowData[item.key];
        });
        defaultValue.value.id = rowData.id;
        formShow.value = true;
    };
    const remove = (rowData) => {
        emit('remove', rowData);
    };
    const importData = () => {
        emit('import');
    };
    const exportData = () => {
        emit('export');
    };
    const formConfirm = (formData) => {
        emit('confirm', formData, formState.value);
    };
</script>
<style scoped lang="scss">
    :deep(.el-table__body-wrapper tr td.el-table-fixed-column--left.is-first-column::before){
        bottom: 0!important;
    }
    :deep(.el-table__body-wrapper tr td.el-table-fixed-column--left.is-last-column::before){
        bottom: 0!important;
    }
    :deep(.el-table__body-wrapper tr td.el-table-fixed-column--right.is-first-column::before){
        bottom: 0!important;
    }
    :deep(.el-table__body-wrapper tr td.el-table-fixed-column--right.is-last-column::before){
        bottom: 0!important;
    }
    .tableoper_container{
        margin-bottom: 10px;
        display: flex;
        justify-content: space-between;
        position: relative;
    }
    .tableoper_container .el-button{
        padding: 5px 10px;
        height: 28px;
        line-height: 28px;
    }
    .table_tool_container{
        width: 150px;height: 40px; 
        position: absolute;
        right: 0;top: 0;
        .el-button{
            width: 32px;
            height: 32px;
        }
    }
    .pagination_container{
        display: flex;
        justify-content: flex-end;
        padding-top: 10px;
        box-sizing: border-box;
    }
</style>